package com.test.json;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.test.entity.Item;

/**
 * JsonTree. <br>
 * JsonTree封装.
 * <p>
 * Copyright: Copyright (c) 2010-4-17 下午04:20:59
 * <p>
 * Company: 北京宽连十方数字技术有限公司
 * <p>
 * Author: liuxl@c-platform.com
 * <p>
 * Version: 1.0
 * <p>
 */
public class JsonTree {

	/**
	 * 获取属性值。 <br>
	 * 
	 * @param object
	 *            object
	 * @param name
	 *            字符串
	 * @return Object
	 */
	private static Object getFieldValue(Object object, String name) {
		try {
			Field field = object.getClass().getDeclaredField(name);
			field.setAccessible(true);
			return field.get(object);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 把item自动转换为平级的tree格式
	 * 
	 * @param itemList
	 *            实体集合
	 * @param textProperty
	 *            显示的名称属性名
	 * @param checkedSet
	 *            被选中的对象
	 * @param checkedProperty
	 *            被选中对象的属性名
	 * @return
	 */
	public static String getJsonNoCheckStringByList(List<? extends Item> itemList, String textProperty, Set<? extends Item> checkedSet,
	        String checkedProperty) {
		Set<Long> checkedIDSet = new HashSet<Long>();
		if (checkedSet != null && !checkedSet.isEmpty()) {
			Iterator i = checkedSet.iterator();
			while (i.hasNext()) {
				Item item = (Item) i.next();
				if (checkedProperty != null && !"".equals(checkedProperty)) {
					checkedIDSet.add((Long) JsonTree.getFieldValue(item, checkedProperty));
				} else {
					checkedIDSet.add(item.getId());
				}
			}
		}
		List<JsonTreeItem> jsonList = new ArrayList<JsonTreeItem>();

		if (itemList != null && !itemList.isEmpty()) {
			int size = itemList.size();
			List<JsonTreeItem> jsonTreeList = new ArrayList<JsonTreeItem>();

			for (int i = 0; i < size; i++) {
				Item item = itemList.get(i);
				Long id = item.getId();
				JsonTreeItem jsonTreeItem = new JsonTreeItem();
				jsonTreeItem.setChecked(checkedIDSet.contains(item.getId()));
				jsonTreeItem.setId(id);
				jsonTreeItem.setLeaf(true);
				jsonTreeItem.setText((String) JsonTree.getFieldValue(item, textProperty));
				jsonTreeList.add(jsonTreeItem);
			}
			String response = com.test.util.JsonUtil.getJsonString4JavaCollection(jsonTreeList, "yyyy-MM-dd").replace("\"children\":[],", "");
			// System.err.println( "err::" + response );
			return response;
		}
		return null;

	}

	/**
	 * 把item自动转换为统一的tree格式
	 * 
	 * @param itemList
	 *            实体集合
	 * @param textProperty
	 *            显示的名称属性名
	 * @param parentProperty
	 *            父对象的属性名
	 * @param checkedIds
	 *            被选中的id数组
	 * @param parentProperty
	 *            被选中对象的属性名
	 * @return
	 */
	public static String getJsonNoCheckStringByList(List<? extends Item> itemList, String textProperty, String parentProperty) {
		return JsonTree.getJsonNoCheckStringByList(itemList, textProperty, parentProperty, 0l);
	}

	public static String getJsonNoCheckStringByList(List<? extends Item> itemList, String textProperty, String parentProperty, Long rootId) {
		Map<Long, JsonTreeNoCheckItem> jsonTreeItemMap = new HashMap<Long, JsonTreeNoCheckItem>();
		Map<Long, List<JsonTreeNoCheckItem>> jsonTreeItemGroupMap = new HashMap<Long, List<JsonTreeNoCheckItem>>();
		List<JsonTreeNoCheckItem> jsonList = new ArrayList<JsonTreeNoCheckItem>();

		if (itemList != null && !itemList.isEmpty()) {
			int size = itemList.size();
			for (int i = 0; i < size; i++) {
				Item item = itemList.get(i);
				Long parentId = (Long) JsonTree.getFieldValue(item, parentProperty);
				parentId = (parentId == null) ? rootId : parentId;
				Long id = item.getId();
				List<JsonTreeNoCheckItem> jsonTreeList = null;

				JsonTreeNoCheckItem parentItem = null;
				JsonTreeNoCheckItem jsonTreeItem = new JsonTreeNoCheckItem();
				jsonTreeItem.setId(id);
				jsonTreeItem.setText((String) JsonTree.getFieldValue(item, textProperty) + "(" + id + ")");
				jsonTreeItem.setChildren(jsonTreeItemGroupMap.get(id));

				if (parentId.equals(rootId)) {
					jsonTreeList = jsonTreeItemGroupMap.get(parentId);
					jsonList.add(jsonTreeItem);
				} else {
					parentItem = jsonTreeItemMap.get(parentId);
					jsonTreeList = jsonTreeItemGroupMap.get(parentId);
				}

				if (jsonTreeList == null) {
					jsonTreeList = new ArrayList<JsonTreeNoCheckItem>();
					jsonTreeItemGroupMap.put(parentId, jsonTreeList);
				}

				if (parentItem != null) {
					parentItem.setChildren(jsonTreeList);
				}
				jsonTreeItemMap.put(id, jsonTreeItem);
				jsonTreeList.add(jsonTreeItem);
			}
		}

		String response = com.test.util.JsonUtil.getJsonString4JavaCollection(jsonList, "yyyy-MM-dd").replace("\"children\":[],", "");
		return response;
	}

	/**
	 * 把item自动转换为统一的tree格式
	 * 
	 * @param itemList
	 *            实体集合
	 * @param textProperty
	 *            显示的名称属性名
	 * @param parentProperty
	 *            父对象的属性名
	 * @return
	 */
	public static String getJsonStringByList(List<? extends Item> itemList, String textProperty, String parentProperty) {
		return JsonTree.getJsonStringByList(itemList, textProperty, parentProperty, null);
	}

	/**
	 * 把item自动转换为统一的tree格式
	 * 
	 * @param itemList
	 *            实体集合
	 * @param textProperty
	 *            显示的名称属性名
	 * @param parentProperty
	 *            父对象的属性名
	 * @return
	 */
	public static String getJsonStringByList(List<? extends Item> itemList, String textProperty, String parentProperty, boolean hasCheckBox) {

		if (hasCheckBox) {
			return JsonTree.getJsonStringByList(itemList, textProperty, parentProperty, null);
		} else {
			return JsonTree.getJsonNoCheckStringByList(itemList, textProperty, parentProperty);
		}
	}

	/**
	 * 把item自动转换为统一的tree格式
	 * 
	 * @param itemList
	 *            实体集合
	 * @param textProperty
	 *            显示的名称属性名
	 * @param parentProperty
	 *            父对象的属性名
	 * @param checkedSet
	 *            被选中的对象数组
	 * @return
	 */
	public static String getJsonStringByList(List<? extends Item> itemList, String textProperty, String parentProperty, Set<? extends Item> checkedSet) {
		return JsonTree.getJsonStringByList(itemList, textProperty, parentProperty, checkedSet, null);
	}

	public static String getJsonStringByIDList(List<? extends Item> itemList, String textProperty, String parentProperty, Set<Long> checkedIDSet) {
		Map<Long, JsonTreeItem> jsonTreeItemMap = new HashMap<Long, JsonTreeItem>();
		Map<Long, List<JsonTreeItem>> jsonTreeItemGroupMap = new HashMap<Long, List<JsonTreeItem>>();
		List<JsonTreeItem> jsonList = new ArrayList<JsonTreeItem>();

		if (itemList != null && !itemList.isEmpty()) {
			int size = itemList.size();
			for (int i = 0; i < size; i++) {
				Item item = itemList.get(i);
				Long parentId = (Long) JsonTree.getFieldValue(item, parentProperty);
				parentId = (parentId == null) ? 0l : parentId;
				Long id = item.getId();
				List<JsonTreeItem> jsonTreeList = null;

				JsonTreeItem parentItem = null;
				JsonTreeItem jsonTreeItem = new JsonTreeItem();
				jsonTreeItem.setChecked(checkedIDSet.contains(item.getId()));
				jsonTreeItem.setId(id);
				jsonTreeItem.setText((String) JsonTree.getFieldValue(item, textProperty));
				jsonTreeItem.setChildren(jsonTreeItemGroupMap.get(id));

				if (parentId == 0l) {
					jsonTreeList = jsonTreeItemGroupMap.get(parentId);
					jsonList.add(jsonTreeItem);
				} else {
					parentItem = jsonTreeItemMap.get(parentId);
					jsonTreeList = jsonTreeItemGroupMap.get(parentId);
				}

				if (jsonTreeList == null) {
					jsonTreeList = new ArrayList<JsonTreeItem>();
					jsonTreeItemGroupMap.put(parentId, jsonTreeList);
				}

				if (parentItem != null) {
					parentItem.setChildren(jsonTreeList);
				}
				jsonTreeItemMap.put(id, jsonTreeItem);
				jsonTreeList.add(jsonTreeItem);
			}
		}

		String response = com.test.util.JsonUtil.getJsonString4JavaCollection(jsonList, "yyyy-MM-dd").replace("\"children\":[],", "");
		// System.err.println( "err::" + response );
		return response;
	}

	/**
	 * 把item自动转换为统一的tree格式
	 * 
	 * @param itemList
	 *            实体集合
	 * @param textProperty
	 *            显示的名称属性名
	 * @param parentProperty
	 *            父对象的属性名
	 * @param checkedSet
	 *            被选中的id数组
	 * @param checkedProperty
	 *            被选中对象的属性名
	 * @return
	 */
	public static String getJsonStringByList(List<? extends Item> itemList, String textProperty, String parentProperty,
	        Set<? extends Item> checkedSet, String checkedProperty) {
		Set<Long> checkedIDSet = new HashSet<Long>();
		if (checkedSet != null && !checkedSet.isEmpty()) {
			Iterator i = checkedSet.iterator();
			while (i.hasNext()) {
				Item item = (Item) i.next();
				if (checkedProperty != null && !"".equals(checkedProperty)) {
					checkedIDSet.add((Long) JsonTree.getFieldValue(item, checkedProperty));
				} else {
					checkedIDSet.add(item.getId());
				}
			}
		}
		return getJsonStringByIDList(itemList, textProperty, parentProperty, checkedIDSet);
	}

	/**
	 * 将对象转换成jsonTree对象。 <br>
	 * <p>
	 * 
	 * @param itemList
	 *            对象列表
	 * @param textProperty
	 *            text字段
	 * @return String jsonTree对象
	 * @throws Exception
	 *             异常说明
	 */
	public static String getJsonTreeByList(List<? extends Item> itemList, String textProperty, boolean leaf) {
		List<JsonTreeNoCheckItem> jsonList = new ArrayList<JsonTreeNoCheckItem>();

		if (itemList != null && !itemList.isEmpty()) {
			int size = itemList.size();
			for (int i = 0; i < size; i++) {
				Item item = itemList.get(i);
				Long id = item.getId();

				JsonTreeNoCheckItem jsonTreeItem = new JsonTreeNoCheckItem();
				jsonTreeItem.setId(id);
				jsonTreeItem.setText((String) JsonTree.getFieldValue(item, textProperty));
				jsonTreeItem.setMark(leaf);
				jsonList.add(jsonTreeItem);
			}
		}
		String response = com.test.util.JsonUtil.getJsonString4JavaCollection(jsonList, "yyyy-MM-dd").replace("\"children\":[],", "");
		return response;
	}
}
